package com.xh3140.android.widget.dialog;


import android.content.Context;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.Size;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.xh3140.android.widget.dialog.callback.ConfigParamsCallback;
import com.xh3140.android.widget.dialog.callback.ConfigParamsListCallback;
import com.xh3140.android.widget.dialog.callback.ConfigViewCallback;
import com.xh3140.android.widget.dialog.listener.OnClickButtonListener;
import com.xh3140.android.widget.dialog.listener.OnCreatedViewListener;
import com.xh3140.android.widget.dialog.params.BaseParams;
import com.xh3140.android.widget.dialog.params.ButtonParams;
import com.xh3140.android.widget.dialog.params.DialogParams;
import com.xh3140.android.widget.dialog.params.SubtitleParams;
import com.xh3140.android.widget.dialog.params.TitleParams;
import com.xh3140.android.widget.dialog.view.ButtonView;
import com.xh3140.android.widget.dialog.view.FooterView;
import com.xh3140.android.widget.dialog.view.HeaderView;
import com.xh3140.android.widget.dialog.view.RootView;
import com.xh3140.android.widget.dialog.view.SubtitleView;
import com.xh3140.android.widget.dialog.view.TitleView;

/**
 * 基础对话框类
 */
@SuppressWarnings("unused")
public abstract class BaseDialog<V extends View> extends AbstractDialog<V> {
    /**
     * 视图创建监听器
     */
    private OnCreatedViewListener<RootView<V>> mOnCreatedRootViewListener;
    private OnCreatedViewListener<HeaderView> mOnCreatedHeadViewListener;
    private OnCreatedViewListener<V> mOnCreatedBodyViewListener;
    private OnCreatedViewListener<FooterView> mOnCreatedFootViewListener;

    public BaseDialog(@NonNull DialogParams params) {
        super(params);
    }

    /**
     * 设置配置根视图回调
     */
    public BaseDialog<V> setOnCreatedRootViewListener(@Nullable OnCreatedViewListener<RootView<V>> listener) {
        mOnCreatedRootViewListener = listener;
        return this;
    }

    /**
     * 设置配置首部视图回调
     */
    public BaseDialog<V> setOnCreatedHeadViewListener(@Nullable OnCreatedViewListener<HeaderView> listener) {
        mOnCreatedHeadViewListener = listener;
        return this;
    }

    /**
     * 设置配置主体视图回调
     */
    public BaseDialog<V> setOnCreatedBodyViewListener(@Nullable OnCreatedViewListener<V> listener) {
        mOnCreatedBodyViewListener = listener;
        return this;
    }

    /**
     * 设置配置底部视图回调
     */
    public BaseDialog<V> setOnCreatedFootViewListener(@Nullable OnCreatedViewListener<FooterView> listener) {
        this.mOnCreatedFootViewListener = listener;
        return this;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 视图创建回调，可以在这些回调里修改样式
        final RootView<V> rootView = requireRootView();
        if (mOnCreatedRootViewListener != null) {
            mOnCreatedRootViewListener.onCreatedView(rootView);
        }
        final HeaderView headerView = rootView.getHeaderView();
        if (headerView != null && mOnCreatedHeadViewListener != null) {
            mOnCreatedHeadViewListener.onCreatedView(headerView);
        }
        final V bodyView = rootView.getBodyView();
        if (bodyView != null && mOnCreatedBodyViewListener != null) {
            mOnCreatedBodyViewListener.onCreatedView(bodyView);
        }
        final FooterView footerView = rootView.getFooterView();
        if (footerView != null && mOnCreatedFootViewListener != null) {
            mOnCreatedFootViewListener.onCreatedView(footerView);
        }
    }

    /**
     * 构建器
     * 配置基础对话框属性
     */
    public static abstract class Builder<D extends BaseDialog<?>, B extends Builder<D, B>> extends AbstractDialog.Builder<D, B> {
        /**
         * 基础对话框属性
         */
        protected final BaseParams<D> mBaseParams;

        public Builder(@NonNull Context context, @IntRange(from = 0) int buttonCount) {
            super(context);
            mBaseParams = new BaseParams<>(context, buttonCount);
        }

        public Builder(@NonNull FragmentActivity activity, @IntRange(from = 0) int buttonCount) {
            super(activity);
            mBaseParams = new BaseParams<>(mDialogParams.context, buttonCount);
        }

        public Builder(@NonNull Fragment fragment, @IntRange(from = 0) int buttonCount) {
            super(fragment);
            mBaseParams = new BaseParams<>(mDialogParams.context, buttonCount);
        }

        /**
         * 转换为继承可用链式编程构建器
         *
         * @return 可以链式编程的构建器
         */
        @SuppressWarnings("unchecked")
        private B toExtendsChainBuilder() {
            return (B) this;
        }

        /**
         * 配置对话框首部视图标题视图属性
         *
         * @param callback 配置回调
         */
        public B configTitleParams(@NonNull ConfigParamsCallback<TitleParams> callback) {
            callback.callback(mBaseParams.header.title);
            return toExtendsChainBuilder();
        }

        /**
         * 配置对话框首部视图副标题视图属性
         *
         * @param callback 配置回调
         */
        public B configSubtitleParams(@NonNull ConfigParamsCallback<SubtitleParams> callback) {
            callback.callback(mBaseParams.header.subtitle);
            return toExtendsChainBuilder();
        }

        /**
         * 配置对话框底部视图按钮视图属性
         *
         * @param position 按钮位置索引
         * @param callback 配置回调
         */
        public B configButtonParams(int position, @NonNull ConfigParamsCallback<ButtonParams> callback) {
            callback.callback(mBaseParams.footer.buttons.get(position));
            return toExtendsChainBuilder();
        }

        /**
         * 配置对话框底部视图所有按钮视图属性
         *
         * @param callback 配置回调
         */
        public B configButtonsParams(@NonNull ConfigParamsListCallback<ButtonParams> callback) {
            callback.callback(mBaseParams.footer.buttons);
            return toExtendsChainBuilder();
        }

        //=============================================================================================//

        /**
         * 设置标题视图文本
         *
         * @param text 文本
         */
        public B setTitleText(@Nullable CharSequence text) {
            mBaseParams.header.title.text = text;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图文本字体大小 sp
         *
         * @param textSize 字体大小
         */
        public B setTitleTextSize(float textSize) {
            mBaseParams.header.title.textSize = textSize;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图文本字体颜色 argb
         *
         * @param textColor 字体颜色
         */
        public B setTitleTextColor(@ColorInt int textColor) {
            mBaseParams.header.title.textColor = textColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图文本字体样式
         *
         * @param typeface 字体样式
         */
        public B setTitleTypeface(int typeface) {
            mBaseParams.header.title.typeface = typeface;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图文本位置
         *
         * @param gravity 位置
         */
        public B setTitleGravity(int gravity) {
            mBaseParams.header.title.gravity = gravity;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图背景颜色 argb
         *
         * @param backgroundColor 背景颜色
         */
        public B setTitleBackgroundColor(@ColorInt int backgroundColor) {
            mBaseParams.header.title.backgroundColor = backgroundColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图内边距
         * 格式：[start, top, end, bottom] px
         *
         * @param padding 边距
         */
        public B setTitlePadding(@Nullable @Size(4) int[] padding) {
            mBaseParams.header.title.padding = padding;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图内边距
         *
         * @param padding 边距 px
         */
        public B setTitlePadding(@Px int padding) {
            mBaseParams.header.title.padding = new int[]{padding, padding, padding, padding};
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图内边距
         *
         * @param left   左边距 px
         * @param top    上边距 px
         * @param right  右边距 px
         * @param bottom 下边距 px
         */
        public B setTitlePadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
            mBaseParams.header.title.padding = new int[]{left, top, right, bottom};
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图外边距
         * 格式：[start, top, end, bottom] px
         *
         * @param margins 边距
         */
        public B setTitleMargins(@Nullable @Size(4) int[] margins) {
            mBaseParams.header.title.margins = margins;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图外边距
         *
         * @param margins 边距 px
         */
        public B setTitleMargins(@Px int margins) {
            mBaseParams.header.title.margins = new int[]{margins, margins, margins, margins};
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图外边距
         *
         * @param left   左边距 px
         * @param top    上边距 px
         * @param right  右边距 px
         * @param bottom 下边距 px
         */
        public B setTitleMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
            mBaseParams.header.title.margins = new int[]{left, top, right, bottom};
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图高度 px
         *
         * @param height 高度
         */
        public B setTitleHeight(@Px int height) {
            mBaseParams.header.title.height = height;
            return toExtendsChainBuilder();
        }

        /**
         * 设置标题视图配置回调
         * 拥有绝对控制权的回调，它在其他属性配置结束后回调
         * 一般情况不要使用它，除非提供的现有配置属性不满足需求
         *
         * @param callback 配置回调
         */
        public B setTitleViewCallback(@Nullable ConfigViewCallback<TitleView> callback) {
            mBaseParams.header.title.callback = callback;
            return toExtendsChainBuilder();
        }

        //=============================================================================================//

        /**
         * 设置副标题视图文本
         *
         * @param text 文本
         */
        public B setSubtitleText(@Nullable CharSequence text) {
            mBaseParams.header.subtitle.text = text;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图文本字体大小 sp
         *
         * @param textSize 字体大小
         */
        public B setSubtitleTextSize(float textSize) {
            mBaseParams.header.subtitle.textSize = textSize;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图文本字体颜色 argb
         *
         * @param textColor 字体颜色
         */
        public B setSubtitleTextColor(@ColorInt int textColor) {
            mBaseParams.header.subtitle.textColor = textColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图文本字体样式
         *
         * @param typeface 字体样式
         */
        public B setSubtitleTypeface(int typeface) {
            mBaseParams.header.subtitle.typeface = typeface;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图文本位置
         *
         * @param gravity 位置
         */
        public B setSubtitleGravity(int gravity) {
            mBaseParams.header.subtitle.gravity = gravity;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图背景颜色 argb
         *
         * @param backgroundColor 背景颜色
         */
        public B setSubtitleBackgroundColor(@ColorInt int backgroundColor) {
            mBaseParams.header.subtitle.backgroundColor = backgroundColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图内边距
         * 格式：[start, top, end, bottom] px
         *
         * @param padding 边距
         */
        public B setSubtitlePadding(@Nullable @Size(4) int[] padding) {
            mBaseParams.header.subtitle.padding = padding;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图内边距
         *
         * @param padding 边距 px
         */
        public B setSubtitlePadding(@Px int padding) {
            mBaseParams.header.subtitle.padding = new int[]{padding, padding, padding, padding};
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图内边距
         *
         * @param left   左边距 px
         * @param top    上边距 px
         * @param right  右边距 px
         * @param bottom 下边距 px
         */
        public B setSubtitlePadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
            mBaseParams.header.subtitle.padding = new int[]{left, top, right, bottom};
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图外边距
         * 格式：[start, top, end, bottom] px
         *
         * @param margins 边距
         */
        public B setSubtitleMargins(@Nullable @Size(4) int[] margins) {
            mBaseParams.header.subtitle.margins = margins;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图外边距
         *
         * @param margins 边距 px
         */
        public B setSubtitleMargins(@Px int margins) {
            mBaseParams.header.subtitle.margins = new int[]{margins, margins, margins, margins};
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图外边距
         *
         * @param left   左边距 px
         * @param top    上边距 px
         * @param right  右边距 px
         * @param bottom 下边距 px
         */
        public B setSubtitleMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
            mBaseParams.header.subtitle.margins = new int[]{left, top, right, bottom};
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图高度 px
         *
         * @param height 高度
         */
        public B setSubtitleHeight(@Px int height) {
            mBaseParams.header.subtitle.height = height;
            return toExtendsChainBuilder();
        }

        /**
         * 设置副标题视图配置回调
         * 拥有绝对控制权的回调，它在其他属性配置结束后回调
         * 一般情况不要使用它，除非提供的现有配置属性不满足需求
         *
         * @param callback 配置回调
         */
        public B setSubtitleViewCallback(@Nullable ConfigViewCallback<SubtitleView> callback) {
            mBaseParams.header.subtitle.callback = callback;
            return toExtendsChainBuilder();
        }

        //=============================================================================================//

        /**
         * 设置按钮视图文本
         *
         * @param texts 文本列表
         */
        public B setButtonsText(CharSequence... texts) {
            for (int i = 0; i < texts.length; ++i) {
                mBaseParams.footer.buttons.get(i).text = texts[i];
            }
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图文本
         *
         * @param position 按钮位置
         * @param text     文本
         */
        public B setButtonText(int position, @Nullable CharSequence text) {
            mBaseParams.footer.buttons.get(position).text = text;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图文本字体大小 sp
         *
         * @param position 按钮位置
         * @param textSize 字体大小
         */
        public B setButtonTextSize(int position, float textSize) {
            mBaseParams.footer.buttons.get(position).textSize = textSize;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图文本字体颜色 argb
         *
         * @param position  按钮位置
         * @param textColor 字体颜色
         */
        public B setButtonTextColor(int position, @ColorInt int textColor) {
            mBaseParams.footer.buttons.get(position).textColor = textColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图是否处于禁用状态
         *
         * @param position 按钮位置
         * @param disable  标识
         */
        public B setButtonDisable(int position, boolean disable) {
            mBaseParams.footer.buttons.get(position).disable = disable;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图禁用状态下的文本字体颜色 argb
         *
         * @param position  按钮位置
         * @param textColor 字体颜色
         */
        public B setButtonDisabledTextColor(int position, @ColorInt int textColor) {
            mBaseParams.footer.buttons.get(position).disabledTextColor = textColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图文本字体样式
         *
         * @param position 按钮位置
         * @param typeface 字体样式
         */
        public B setButtonTypeface(int position, int typeface) {
            mBaseParams.footer.buttons.get(position).typeface = typeface;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图背景颜色 argb
         *
         * @param position        按钮位置
         * @param backgroundColor 背景颜色
         */
        public B setButtonBackgroundColor(int position, @ColorInt int backgroundColor) {
            mBaseParams.footer.buttons.get(position).backgroundColor = backgroundColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图按下状态背景颜色 argb
         *
         * @param position        按钮位置
         * @param backgroundColor 背景颜色
         */
        public B setButtonPressedBackgroundColor(int position, @ColorInt int backgroundColor) {
            mBaseParams.footer.buttons.get(position).pressedBackgroundColor = backgroundColor;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图内边距
         * 格式：[start, top, end, bottom] px
         *
         * @param position 按钮位置
         * @param padding  边距
         */
        public B setButtonPadding(int position, @Nullable @Size(4) int[] padding) {
            mBaseParams.footer.buttons.get(position).padding = padding;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图内边距
         *
         * @param position 按钮位置
         * @param padding  边距 px
         */
        public B setButtonPadding(int position, @Px int padding) {
            mBaseParams.footer.buttons.get(position).padding = new int[]{padding, padding, padding, padding};
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图内边距
         *
         * @param position 按钮位置
         * @param left     左边距 px
         * @param top      上边距 px
         * @param right    右边距 px
         * @param bottom   下边距 px
         */
        public B setButtonPadding(int position, @Px int left, @Px int top, @Px int right, @Px int bottom) {
            mBaseParams.footer.buttons.get(position).padding = new int[]{left, top, right, bottom};
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图外边距
         * 格式：[start, top, end, bottom] px
         *
         * @param position 按钮位置
         * @param margins  边距
         */
        public B setButtonMargins(int position, @Nullable @Size(4) int[] margins) {
            mBaseParams.footer.buttons.get(position).margins = margins;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图外边距
         *
         * @param position 按钮位置
         * @param margins  边距 px
         */
        public B setButtonMargins(int position, @Px int margins) {
            mBaseParams.footer.buttons.get(position).margins = new int[]{margins, margins, margins, margins};
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图外边距
         *
         * @param position 按钮位置
         * @param left     左边距 px
         * @param top      上边距 px
         * @param right    右边距 px
         * @param bottom   下边距 px
         */
        public B setButtonMargins(int position, @Px int left, @Px int top, @Px int right, @Px int bottom) {
            mBaseParams.footer.buttons.get(position).margins = new int[]{left, top, right, bottom};
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图高度 px
         *
         * @param position 按钮位置
         * @param height   高度
         */
        public B setButtonHeight(int position, @Px int height) {
            mBaseParams.footer.buttons.get(position).height = height;
            return toExtendsChainBuilder();
        }

        /**
         * 设置按钮视图配置回调
         * 拥有绝对控制权的回调，它在其他属性配置结束后回调
         * 一般情况不要使用它，除非提供的现有配置属性不满足需求
         *
         * @param callback 配置回调
         */
        public B setButtonViewCallback(int position, @Nullable ConfigViewCallback<ButtonView> callback) {
            mBaseParams.footer.buttons.get(position).callback = callback;
            return toExtendsChainBuilder();
        }

        //=============================================================================================//

        /**
         * 设置对话框底部视图按钮点击监听器
         *
         * @param listener 监听器
         */
        public B setButtonOnClickListener(@Nullable OnClickButtonListener<D> listener) {
            mBaseParams.footer.listener = listener;
            return toExtendsChainBuilder();
        }
    }
}






